/* * Copyright (c) 2004, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */ package org.postgresql.test.jdbc2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.postgresql.test.TestUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.TimeZone; /* * Some simple tests based on problems reported by users. Hopefully these will help prevent previous * problems from re-occurring ;-) * */ public class TimeTest { private Connection con; private boolean testSetTime = false; @Before public void setUp() throws Exception { con = TestUtil.openDB(); TestUtil.createTempTable(con, "testtime", "tm time, tz time with time zone"); } @After public void tearDown() throws Exception { TestUtil.dropTable(con, "testtime"); TestUtil.closeDB(con); } private long extractMillis(long time) { return (time >= 0) ? (time % 1000) : (time % 1000 + 1000); } /* * * Test use of calendar */ @Test public void testGetTimeZone() throws Exception { final Time midnight = new Time(0, 0, 0); Statement stmt = con.createStatement(); Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("GMT")); int localOffset = Calendar.getInstance().getTimeZone().getOffset(midnight.getTime()); // set the time to midnight to make this easy assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'00:00:00','00:00:00'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'00:00:00.1','00:00:00.01'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "CAST(CAST(now() AS timestamp without time zone) AS time),now()"))); ResultSet rs = stmt.executeQuery(TestUtil.selectSQL("testtime", "tm,tz")); assertNotNull(rs); assertTrue(rs.next()); Time time = rs.getTime(1); Timestamp timestamp = rs.getTimestamp(1); assertNotNull(timestamp); Timestamp timestamptz = rs.getTimestamp(2); assertNotNull(timestamptz); assertEquals(midnight, time); time = rs.getTime(1, cal); assertEquals(midnight.getTime(), time.getTime() - localOffset); assertTrue(rs.next()); time = rs.getTime(1); assertNotNull(time); assertEquals(100, extractMillis(time.getTime())); timestamp = rs.getTimestamp(1); assertNotNull(timestamp); assertEquals(100, extractMillis(timestamp.getTime())); assertEquals(100000000, timestamp.getNanos()); Time timetz = rs.getTime(2); assertNotNull(timetz); assertEquals(10, extractMillis(timetz.getTime())); timestamptz = rs.getTimestamp(2); assertNotNull(timestamptz); assertEquals(10, extractMillis(timestamptz.getTime())); assertEquals(10000000, timestamptz.getNanos()); assertTrue(rs.next()); time = rs.getTime(1); assertNotNull(time); timestamp = rs.getTimestamp(1); assertNotNull(timestamp); timetz = rs.getTime(2); assertNotNull(timetz); timestamptz = rs.getTimestamp(2); assertNotNull(timestamptz); } /* * Tests the time methods in ResultSet */ @Test public void testGetTime() throws SQLException { Statement stmt = con.createStatement(); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'01:02:03'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'23:59:59'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'12:00:00'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'05:15:21'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'16:21:51'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'12:15:12'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'22:12:01'"))); assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL("testtime", "'08:46:44'"))); // Fall through helper timeTest(); assertEquals(8, stmt.executeUpdate("DELETE FROM testtime")); stmt.close(); } /* * Tests the time methods in PreparedStatement */ @Test public void testSetTime() throws SQLException { PreparedStatement ps = con.prepareStatement(TestUtil.insertSQL("testtime", "?")); Statement stmt = con.createStatement(); ps.setTime(1, makeTime(1, 2, 3)); assertEquals(1, ps.executeUpdate()); ps.setTime(1, makeTime(23, 59, 59)); assertEquals(1, ps.executeUpdate()); ps.setObject(1, Time.valueOf("12:00:00"), java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, Time.valueOf("05:15:21"), java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, Time.valueOf("16:21:51"), java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, Time.valueOf("12:15:12"), java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, "22:12:1", java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, "8:46:44", java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, "5:1:2-03", java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); ps.setObject(1, "23:59:59+11", java.sql.Types.TIME); assertEquals(1, ps.executeUpdate()); // Need to let the test know this one has extra test cases. testSetTime = true; // Fall through helper timeTest(); testSetTime = false; assertEquals(10, stmt.executeUpdate("DELETE FROM testtime")); stmt.close(); ps.close(); } /* * Helper for the TimeTests. It tests what should be in the db */ private void timeTest() throws SQLException { Statement st = con.createStatement(); ResultSet rs; Time t; rs = st.executeQuery(TestUtil.selectSQL("testtime", "tm")); assertNotNull(rs); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(1, 2, 3), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(23, 59, 59), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(12, 0, 0), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(5, 15, 21), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(16, 21, 51), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(12, 15, 12), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(22, 12, 1), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); assertEquals(makeTime(8, 46, 44), t); // If we're checking for timezones. if (testSetTime) { assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); Time tmpTime = Time.valueOf("5:1:2"); int localOffset = Calendar.getInstance().getTimeZone().getOffset(tmpTime.getTime()); int timeOffset = 3 * 60 * 60 * 1000; tmpTime.setTime(tmpTime.getTime() + timeOffset + localOffset); assertEquals(makeTime(tmpTime.getHours(), tmpTime.getMinutes(), tmpTime.getSeconds()), t); assertTrue(rs.next()); t = rs.getTime(1); assertNotNull(t); tmpTime = Time.valueOf("23:59:59"); localOffset = Calendar.getInstance().getTimeZone().getOffset(tmpTime.getTime()); timeOffset = -11 * 60 * 60 * 1000; tmpTime.setTime(tmpTime.getTime() + timeOffset + localOffset); assertEquals(makeTime(tmpTime.getHours(), tmpTime.getMinutes(), tmpTime.getSeconds()), t); } assertTrue(!rs.next()); rs.close(); } private Time makeTime(int h, int m, int s) { return Time.valueOf(TestUtil.fix(h, 2) + ":" + TestUtil.fix(m, 2) + ":" + TestUtil.fix(s, 2)); } }